<template>
  <div
    class="grimm-tab-bar"
    :class="{
      'grimm-tab-bar-large-card': showOneLevelCard,
      'grimm-tab-bar-small-card': showSecondLevelCard,
    }"
  >
    <slot>
      <grimm-tab
        v-for="item in data"
        :label="item.label"
        :value="item.value"
        :icon="item.icon"
        :key="item.value"
        :showTitle="showTitle"
        :showOneLevelCard="showOneLevelCard"
        :showSecondLevelCard="showSecondLevelCard"
      ></grimm-tab>
    </slot>
    <div v-if="showSlider" ref="slider" class="grimm-tab-bar-slider"></div>
  </div>
</template>
<script>
import { prefixStyle } from '../../common/helpers/dom';
import { findIndex } from '../../common/helpers/util';
import GrimmTab from './tab.vue';

const name = 'grimm-tab-bar';

const TRANSFORM = prefixStyle('transform');
const TRANSITION = prefixStyle('transition');

export default {
  name: name,
  components: {
    GrimmTab,
  },
  props: {
    value: {
      type: [String, Number],
      required: true,
    },
    showTitle: {
      type: Boolean,
      default: true,
    },
    data: {
      type: Array,
      default() {
        return [];
      },
    },
    inline: {
      type: Boolean,
      default: false,
    },
    showSlider: {
      type: Boolean,
      default: false,
    },
    useTransition: {
      type: Boolean,
      default: true,
    },
    showOneLevelCard: {
      type: Boolean,
      default: false,
    },
    showSecondLevelCard: {
      type: Boolean,
      default: false,
    },
  },
  computed: {
    showCard() {
      let style = '';
      if (this.$parent.showOneLevelCard) {
        style = 'grimm-tab-bar-large-card';
      } else if (this.$parent.showSecondLevelCard) {
        style = 'grimm-tab-bar-small-card';
      }
      return style;
    },
  },
  watch: {
    value() {
      this.updateSliderStyle();
    },
  },
  created() {
    this.tabs = [];
  },
  mounted() {
    this.updateSliderStyle();
  },
  methods: {
    addTab(tab) {
      this.tabs.push(tab);
    },
    removeTab(tab) {
      const index = this.tabs.indexOf(tab);
      if (index > -1) this.tabs.splice(index, 1);
    },
    trigger(label, value) {
      this.$emit('click', value, label);
      if (value !== this.value) {
        const changedEvents = ['input', 'change'];
        changedEvents.forEach(eventType => {
          this.$emit(eventType, value, label);
        });
      }
    },
    updateSliderStyle() {
      if (!this.showSlider) return;
      const { slider } = this.$refs;
      this.$nextTick(() => {
        const { width, index } = this.getSliderWidthAndIndex();
        slider.style.width = `${Math.floor(width / 2)}px`;
        this.setSliderTransform(this.getOffsetLeft(index));
      });
    },
    setSliderTransform(offset) {
      const { width } = this.getSliderWidthAndIndex();
      const { slider } = this.$refs;
      if (typeof offset === 'number') {
        offset = `${offset + Math.floor(width / 4)}px`;
      }
      if (slider) {
        if (this.useTransition) slider.style[TRANSITION] = `${TRANSFORM} 0.2s linear`;
        slider.style[TRANSFORM] = `translateX(${offset}) translateZ(0)`;
      }
    },
    getSliderWidthAndIndex() {
      let width = 0;
      let index = 0;
      if (this.tabs.length > 0) {
        index = findIndex(this.tabs, tab => tab.value === this.value);
        width = this.tabs[index].$el.clientWidth;
      }
      return {
        width,
        index,
      };
    },
    getOffsetLeft(index) {
      return this.tabs[index].$el.offsetLeft || 0;
    },
  },
};
</script>
<style></style>
